<template>
	<el-upload
		:class="{ uoloadSty: state.showBtnImg, disUoloadSty: state.noneBtnImg }"
		:action="myAction"
		:list-type="fileType"
		:accept="acceptSuffix"
		ref="upload"
		:auto-upload="true"
		:on-change="uploadChange"
		:on-success="uploadSuccess"
		:on-remove="uploadRemove"
		:on-exceed="uploadExceed"
		:on-error="fileError"
    :on-preview="handlePictureCardPreview"
		:before-upload="beforeUpload"
		:before-remove="beforeRemove"
		:limit="limit"
		:file-list="state.fileList"
		:disabled="isDisabled"
	>
		<el-icon v-if="fileType === 'picture-card'" class="uploader-icon"><ele-Plus /></el-icon>
		<el-button type="primary" v-else>点击上传</el-button>
		<template #tip>
			<div class="el-upload__tip">{{ tip }}</div>
		</template>
	</el-upload>
  <el-dialog v-model="state.dialogVisible">
    <img w-full :src="state.dialogImageUrl" alt="Preview Image" />
  </el-dialog>
</template>

<script setup lang="ts" name="uploadFile">
import { ElMessage } from 'element-plus';
import { reactive, watch, computed } from 'vue';

// 定义父组件传过来的值
const props = defineProps({
	imgList: {
		type: Array,
		default: () => <EmptyArrayType>[],
	},
	limit: {
		type: Number,
		default: 1,
	},
	imgSize: {
		type: Number,
		default: 5,
	},
	imgUnit: {
		type: String,
		default: 'MB',
	},
	canRemove: {
		type: Boolean,
		default: true,
	},
	isDisabled: {
		type: Boolean,
		default: false,
	},
	fileType: {
		type: String,
		default: 'picture-card', //text/picture/picture-card
	},
	acceptSuffix: {
		type: String,
		default: '*',
	},
	tip: {
		type: String,
		default: '',
	},
	maxWidth: {
		type: Number,
		default: 0,
	},
	maxHeight: {
		type: Number,
		default: 0,
	},
});

const myAction = computed(() => {
	return 'api/v1/uploadFileV1';
});

const state = reactive({
	fileList: <any>[],
	showBtnImg: true,
	noneBtnImg: false,
  dialogVisible: false,
  dialogImageUrl: '',
});

const emit = defineEmits(['uploadSuccess', 'fileError', 'uploadRemove', 'uploadExceed']);

watch(
	() => props.imgList,
	() => {
    state.fileList = props.imgList;
    if (props.limit <= state.fileList.length) {
      state.noneBtnImg = true;
    } else {
      state.noneBtnImg = false;
    }
	},
	{
		deep: true,
	}
);

//限制图片上传大小
const beforeUpload = (file: any) => {
	let unit = 'MB';
	let size = 2;
	if (props.imgUnit) {
		unit = props.imgUnit;
	}
	if (props.imgSize) {
		size = props.imgSize;
	}
	if (unit == 'MB') {
		size = 1024 * 1024 * size;
	} else if (unit == 'KB') {
		size = 1024 * size;
	} else {
		unit = 'B';
	}
	const isLt2M = file.size < size;
	// 上传图片大小判断
	if (!isLt2M) {
		ElMessage.error('上传文件大小不能超过 ' + (unit == 'MB' ? size / 1024 / 1024 : unit == 'KB' ? size / 1024 : size) + unit + '!');
	}
	// 上传图片尺寸判断
	if (props.maxWidth !== 0 || props.maxHeight !== 0) {
		const isSize = new Promise(function (resolve, reject) {
			let width = props.maxWidth;
			let height = props.maxHeight;
			let _URL = window.URL || window.webkitURL;
			let img = new Image();
			img.onload = function () {
				let valid = img.width > width || img.height > height;
				valid ? resolve(valid) : reject();
			};
			img.src = _URL.createObjectURL(file);
		}).then(
			() => {
				return file;
			},
			(e) => {
				ElMessage.error('上传的文件尺寸需大于等于' + props.maxWidth + '*' + props.maxHeight);
				return Promise.reject();
			}
		);
		return isSize;
	}
	// 上传图片后缀判断
	if (props.acceptSuffix != '*') {
		const fileExt = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase();
		const whiteExt = props.acceptSuffix.split(',');
		if (whiteExt.indexOf('.' + fileExt) === -1) {
			ElMessage.error('上传文件只能是:' + props.acceptSuffix + '文件');
			return false;
		}
	}
	return isLt2M;
};
const beforeRemove = () => {
	if (props.canRemove == false) {
		return false;
	}
};

const uploadChange = (file: any, fileList: any) => {
	if (props.limit <= fileList.length) {
		state.noneBtnImg = true;
	} else {
		state.noneBtnImg = false;
	}
};

const uploadSuccess = (response:any) => {
	// 返回数据处理
	if (response.status === 'success') {
		state.fileList.push(response.data);
		emit('uploadSuccess', state.fileList);
	}
};

// 上传图片失败回调
const fileError = (err: any) => {
	emit('fileError', err);
};

// 删除图片回调
const uploadRemove = (file: any, fileArr: any) => {
	state.fileList = fileArr;
	emit('uploadRemove', state.fileList);
	if (props.limit <= state.fileList.length) {
		state.noneBtnImg = true;
	} else {
		state.noneBtnImg = false;
	}
};
//上传最大限制回调
const uploadExceed = (res: any) => {
	emit('uploadExceed', res);
	ElMessage.error('最多上传！' + props.limit + '个文件');
};

// 放大镜
const handlePictureCardPreview = (uploadFile:any) => {
  state.dialogImageUrl = uploadFile.url!
  state.dialogVisible = true
}
</script>
<style scoped lang="scss">
.uoloadSty {
	float: left;
}
.uoloadSty .el-upload--picture-card {
	/*width:110px;*/
	/*height:110px;*/
	/*line-height:110px;*/
}
.disUoloadSty :deep(.el-upload--picture-card) {
	display: none; /* 上传按钮隐藏 */
}
.el-upload-list__item.is-ready {
	display: none;
}
:deep(.el-upload-list__item) {
	transition: none !important;
}

.el-icon.uploader-icon {
	font-size: 28px;
	color: #8c939d;
	width: 178px;
	height: 178px;
	text-align: center;
}
:deep(.el-dialog__body) {
  text-align: center;
}
</style>
